package com.laundry.user.data.api

import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * 网络模块配置
 */
object NetworkModule {
    
    private const val BASE_URL = "https://api.laundryhelp.com/v1/"
    private const val CONNECT_TIMEOUT = 30L
    private const val READ_TIMEOUT = 30L
    private const val WRITE_TIMEOUT = 30L
    private const val CACHE_SIZE = 10 * 1024 * 1024L // 10MB
    
    private var apiService: ApiService? = null
    private var tokenManager: TokenManager? = null
    
    /**
     * 初始化网络模块
     */
    fun initialize(context: Context) {
        tokenManager = TokenManager(context)
        
        val gson = GsonBuilder()
            .setDateFormat("yyyy-MM-dd HH:mm:ss")
            .create()
        
        val okHttpClient = createOkHttpClient(context)
        
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
        
        apiService = retrofit.create(ApiService::class.java)
    }
    
    /**
     * 获取API服务实例
     */
    fun getApiService(): ApiService {
        return apiService ?: throw IllegalStateException("NetworkModule not initialized")
    }
    
    /**
     * 获取Token管理器
     */
    fun getTokenManager(): TokenManager {
        return tokenManager ?: throw IllegalStateException("NetworkModule not initialized")
    }
    
    /**
     * 创建OkHttpClient
     */
    private fun createOkHttpClient(context: Context): OkHttpClient {
        val builder = OkHttpClient.Builder()
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            .cache(createCache(context))
            .addInterceptor(createAuthInterceptor())
            .addInterceptor(createCommonInterceptor())
        
        // 添加日志拦截器（仅在Debug模式下）
        if (com.laundry.user.BuildConfig.DEBUG) {
            val loggingInterceptor = HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            }
            builder.addInterceptor(loggingInterceptor)
        }
        
        return builder.build()
    }
    
    /**
     * 创建缓存
     */
    private fun createCache(context: Context): Cache {
        val cacheDir = File(context.cacheDir, "http_cache")
        return Cache(cacheDir, CACHE_SIZE)
    }
    
    /**
     * 创建认证拦截器
     */
    private fun createAuthInterceptor(): Interceptor {
        return Interceptor { chain ->
            val originalRequest = chain.request()
            val token = tokenManager?.getAccessToken()
            
            val newRequest = if (!token.isNullOrEmpty()) {
                originalRequest.newBuilder()
                    .header("Authorization", "Bearer $token")
                    .build()
            } else {
                originalRequest
            }
            
            val response = chain.proceed(newRequest)
            
            // 处理Token过期
            if (response.code == 401) {
                response.close()

                // Token过期，清除Token并跳转到登录页
                tokenManager?.clearTokens()
                // TODO: 发送登录过期事件
            }
            
            response
        }
    }
    
    /**
     * 创建通用拦截器
     */
    private fun createCommonInterceptor(): Interceptor {
        return Interceptor { chain ->
            val originalRequest = chain.request()
            
            val newRequest = originalRequest.newBuilder()
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .header("User-Agent", createUserAgent())
                .header("X-Platform", "android")
                .header("X-App-Version", com.laundry.user.BuildConfig.VERSION_NAME)
                .build()
            
            chain.proceed(newRequest)
        }
    }
    
    /**
     * 创建User-Agent
     */
    private fun createUserAgent(): String {
        return "LaundryUser/${com.laundry.user.BuildConfig.VERSION_NAME} " +
                "(Android ${android.os.Build.VERSION.RELEASE}; " +
                "${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL})"
    }
}

/**
 * Token管理器
 */
class TokenManager(private val context: Context) {
    
    private val prefs = context.getSharedPreferences("auth_prefs", Context.MODE_PRIVATE)
    
    companion object {
        private const val KEY_ACCESS_TOKEN = "access_token"
        private const val KEY_REFRESH_TOKEN = "refresh_token"
        private const val KEY_TOKEN_EXPIRES_AT = "token_expires_at"
    }
    
    /**
     * 保存Token
     */
    fun saveTokens(accessToken: String, refreshToken: String, expiresIn: Long) {
        val expiresAt = System.currentTimeMillis() + (expiresIn * 1000)
        prefs.edit()
            .putString(KEY_ACCESS_TOKEN, accessToken)
            .putString(KEY_REFRESH_TOKEN, refreshToken)
            .putLong(KEY_TOKEN_EXPIRES_AT, expiresAt)
            .apply()
    }
    
    /**
     * 获取访问Token
     */
    fun getAccessToken(): String? {
        return prefs.getString(KEY_ACCESS_TOKEN, null)
    }
    
    /**
     * 获取刷新Token
     */
    fun getRefreshToken(): String? {
        return prefs.getString(KEY_REFRESH_TOKEN, null)
    }
    
    /**
     * 检查Token是否过期
     */
    fun isTokenExpired(): Boolean {
        val expiresAt = prefs.getLong(KEY_TOKEN_EXPIRES_AT, 0)
        return System.currentTimeMillis() >= expiresAt - 60000 // 提前1分钟刷新
    }
    
    /**
     * 刷新Token
     */
    suspend fun refreshToken(): Boolean {
        return try {
            val refreshToken = getRefreshToken() ?: return false
            val request = RefreshTokenRequest(refreshToken)
            val response = NetworkModule.getApiService().refreshToken(request)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val loginResponse = response.body()?.data
                if (loginResponse != null) {
                    saveTokens(
                        loginResponse.accessToken,
                        loginResponse.refreshToken,
                        loginResponse.expiresIn
                    )
                    true
                } else {
                    false
                }
            } else {
                false
            }
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }
    
    /**
     * 清除所有Token
     */
    fun clearTokens() {
        prefs.edit()
            .remove(KEY_ACCESS_TOKEN)
            .remove(KEY_REFRESH_TOKEN)
            .remove(KEY_TOKEN_EXPIRES_AT)
            .apply()
    }
    
    /**
     * 检查是否已登录
     */
    fun isLoggedIn(): Boolean {
        return !getAccessToken().isNullOrEmpty() && !isTokenExpired()
    }
}
